package com.xhj.joffer.array;

import org.testng.annotations.Test;

import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;

import static java.lang.System.currentTimeMillis;
/** @author haijianxia pure_xhj@163.com @Date 2021-08-31 @Time 10:04 */
public class FibonnachiArrayDemo {
  public static void main(String[] args) {
    System.out.println("==========================Fb==========================");
    //	  long n=1900000000;
    //	  long fbn = test01(n);
    //    System.out.println("fbn = " + fbn);
    //	  long fbn3 = test03(n);
    //    System.out.println("fbn3 = " + fbn3);

    System.out.println("==========================青蛙==========================");
    long nq = 20;
    long l = test04(nq);
    System.out.println("l = " + l);
  }
  /** 计算Fibonnachi数列第n项-单机版 */
  @Test
  public static long test01(long n) {
    System.out.println("=============test01==============");
    System.out.println("计算Fibonnachi数列第n项-单机版");
    long time01 = currentTimeMillis();

    long result = 0;
    if (n == 0) {
      result = 0;
    } else {
    }
    if (n == 1) {
      result = 1;
    } else {
    }
    if (n > 1) {
      result = test01(n - 1) + test01(n - 2);
    } else {
    }

    long time0101 = currentTimeMillis() - time01;
    System.out.println("\ntest01 耗时 =  " + time0101 + "ms");
    System.out.println("=================================");

    return result;
  }

  /** Fibonachi n, 累加版 */
  @Test
  public static long test03(long n) {
    System.out.println("=============test03==============");
    System.out.println("Fibonachi n, 累加版");
    long time03 = currentTimeMillis();

    long result = 0;
    if (n == 0) {
      result = 0;
    } else {
    }
    if (n == 1) {
      result = 1;
    } else {
    }
    long a = 1, b = 0;
    for (int i = 0; i < n - 1; i++) {
      result = a + b;
      b = a;
      a = result;
    }

    long time0303 = currentTimeMillis() - time03;
    System.out.println("\ntest03 耗时 =  " + time0303 + "ms");
    System.out.println("=================================");

    return result;
  }

  /** Fibonnachi n, 并发版 */
  @Test
  public long test02(long n) {
    System.out.println("=============test02==============");
    System.out.println("Fibonnachi n, 并发版");
    long time02 = currentTimeMillis();

    Callable callable =
        new Callable() {
          @Override
          public Long call() throws Exception {
            // todo
            return 0L;
          }
        };
    FutureTask<Long> longFutureTask = new FutureTask<Long>(callable);
    Thread ft1 = new Thread(longFutureTask, "ft1");
    Thread ft2 = new Thread(longFutureTask, "ft2");
    ft1.start();

    long result = 0;
    for (int i = 0; i < n - 1; i++) {
      new Thread(
              () -> {
                System.out.println(Thread.currentThread().getName() + " come in...");
              },
              "t" + i)
          .start();
    }

    long time0202 = currentTimeMillis() - time02;
    System.out.println("\ntest 02耗时 =  " + time0202 + "ms");
    System.out.println("=================================");

    return result;
  }

  /** 青蛙跳台阶, 一次可以跳一个或两个台阶, 求n个台阶会有几种跳法? */
  @Test
  public static long test04(long n) {
    System.out.println("=============test04==============");
    System.out.println("青蛙跳台阶");
    long time04 = currentTimeMillis();

    long result = 0;
    if (n == 0) {
      result = 0;
    }
    if (n == 1) {
      result = 1;
    }
    if (n == 2) {
      result = 2;
    } else {
    }
    if (n > 2) {
      result = test04(n - 1) + test04(n - 2);
    } else {
    }

    long time0404 = currentTimeMillis() - time04;
    System.out.println("\ntest04 耗时 =  " + time0404 + "ms");
    System.out.println("=================================");

    return result;
  }

  /** 青蛙跳台阶-plus: 假设有n级台阶, 一次可跳1级或n级, 问:共有几种跳法? */
  @Test
  public void test05(long n) {
    System.out.println("=============test05==============");
    System.out.println("青蛙跳台阶-plus");
    long time05 = currentTimeMillis();

    // fn:
    /** fn:跳到第几级 n-1 n-2 ... 0 */
    long result = 0;
    if (n == 0) {
      result = 0;
    }
    if (n == 1) {
      result = 1;
    }
    if (n == 2) {
      result = 2;
    } else {
    }
    if (n > 2) {
      result = test04(n - 1) + test04(n - 2);
    } else {
    }

    long time0505 = currentTimeMillis() - time05;
    System.out.println("\ntest05 耗时 =  " + time0505 + "ms");
    System.out.println("=================================");
  }
}
